from typing import Dict, List

K = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
R = [1,2,3]

# 机器映射
machine_map = {
    1: "PM1", 2: "PM2", 3: "PM3", 4: "PM4", 5: "PM5", 6: "PM6", 7: "PM7", 8: "PM8", 9: "PM9", 10: "PM10",
    11: "LLA", 12: "LLB", 13: "LLC", 14: "LLD",
    15: "AL"
}

# 机械手映射（与你提供的 TM_map 对应）
TM_map = {1: "TM1", 2: "TM2", 3: "TM3"}



class Job:
    '''
    工件类
    '''
    def __init__(self,name: str, ops_nums: int, feasible_rules: Dict[int, List[int]], process_time_rules: Dict[int, List[int]], transport_rules: Dict[int, List[int]]):
        self.name  = name          # 工件类型名称
        self.ops_nums = ops_nums      # 每个工件的工序数
        self.feasible_rules = feasible_rules  # 各工序可行机器
        self.process_time_rules = process_time_rules  # 各工序加工时间
        self.transport_rules = transport_rules  # 各工序可用机械手

    def print_job_info(self):
        """打印工件的详细信息，包括各工序的配置"""
        print(f"===== 工件信息：{self.name} =====")
        print(f"总工序数：{self.ops_nums}\n")

        # 按工序顺序打印详细配置
        for step in range(1, self.ops_nums + 1):
            print(f"工序 {step}：")
            print(f"  可行机器编号：{self.feasible_rules.get(step, [])}")
            print(f"  加工时间：{self.process_time_rules.get(step, [])}")
            print(f"  可用机械手：{self.transport_rules.get(step, [])}")
            print("-" * 40)  # 工序分隔线



class create_job:
    '''
    生成不同类型的工件
    '''


    def generator_job_a(self) -> Job:
        """
            A工件
          AL[8] - LLA[15]-(PM7[70]-PM8[70]-LLC-LLD[70]-LLB)*5
        """
        # 基础步骤（前2步）+ 循环5次的步骤（每次4步）= 2 + 5*4 = 22步
        feasible = {
            1: [15],  # AL[8]
            2: [11]  # LLA[15]
        }
        process_time = {
            1: [8],  # AL加工时间
            2: [15]  # LLA加工时间
        }
        transport = {
            1: [1],  # AL对应的机械手
            2: [1]  # LLA对应的机械手
        }

        # 循环5次：PM7→PM8→LLC→LLD-LLB
        for cycle in range(5):
            step_base = 2 + cycle * 5  # 循环起始步骤编号
            feasible.update({
                step_base + 1: [7],  # PM7
                step_base + 2: [8],  # PM8
                step_base + 3: [13],  # LLC
                step_base + 4: [14],  # LLD
                step_base + 5: [12]
            })
            if cycle !=4:
                process_time.update({
                    step_base + 1: [70],  # PM7加工时间
                    step_base + 2: [70],  # PM8加工时间
                    step_base + 3: [0],  # LLC加工时间
                    step_base + 4: [70],  # LLD加工时间
                    step_base + 5: [0]
                })
            else:
                # 最后一次循环，需要添加充气时间
                process_time.update({
                    step_base + 1: [70],  # PM7加工时间
                    step_base + 2: [70],  # PM8加工时间
                    step_base + 3: [0],  # LLC加工时间
                    step_base + 4: [70],  # LLD加工时间
                    step_base + 5: [20]
                })
            transport.update({
                step_base + 1: [2],  # PM7对应的机械手
                step_base + 2: [2],  # PM8对应的机械手
                step_base + 3: [2],  # LLC对应的机械手
                step_base + 4: [2],  # LLD对应的机械手
                step_base + 5: [2]
            })

        job_a = Job(
            name="Job_A",
            ops_nums=22,  # 总工序数：2 + 5*4 = 22
            feasible_rules=feasible,
            process_time_rules=process_time,
            transport_rules=transport
        )
        return job_a

    def generator_job_b(self) -> Job:
        """
        工件B: AL[8] - LLA/LLB[15]-PM7/PM8[70]-LLC-PM1/PM2[300]-LLD[70]-LLA/LLB[20]
        :return:
        """
        job_b = Job(
            name="Job_B",
            ops_nums=7,
            feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [1, 2], 6: [14], 7: [11, 12]},
            process_time_rules={1: [8],  2: [15],  3: [70], 4: [70],  5: [300],  6: [70], 7: [20]},
            transport_rules={1: [1], 2: [1], 3: [2], 4: [2],  5: [3],  6: [3],  7: [2]}
        )

        return job_b

    def generator_job_c(self) -> Job:
        """
        工件C
        :return:
        AL[8]-LLA/LLB[15]-PM7/PM8[70]-LLC[0]-PM1/PM2/PM3/PM4[600]-LLD[0]-PM9/PM10[200]-LLA/LLB[90]
        """
        job_c = Job(
                name="Job_C",
                ops_nums=8,
                feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [1, 2, 3, 4], 6: [14], 7: [9, 10], 8: [11, 12]},
                process_time_rules={1: [8], 2: [15], 3: [70], 4: [0], 5: [600], 6: [0], 7: [200], 8: [90]},
                transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [3], 6: [3], 7: [2], 8: [2]}
        )

        return job_c

    def generator_job_d(self) -> Job :
        """工件D"""
        job_d = Job(
            name="Job_D",
            ops_nums=6,  # 每个工件6道工序
            feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [9, 10], 5: [14], 6: [11, 12]},
            process_time_rules={1: [8], 2: [15], 3: [70], 4: [200], 5: [70], 6: [20]},
            transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [2], 6: [2]}
        )
        return job_d

    def generator_job_e(self) -> Job :
        """
            工艺路径为 E 的工件
            AL[8] - LLA/LLB[15] -PM7/PM8[70]-LLC-PM1[600]-LLD[70]-LLA/LLB[20]
        """
        job_e = Job(name="Job_E",
                    ops_nums=7,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [1], 6: [14], 7: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [0], 5: [600], 6: [70], 7: [20]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [1], 6: [1], 7: [2]})

        return job_e

    def generator_job_f(self) -> Job :
        """
        工艺路径为 F 的工件：
         AL[8] - LLA/LLB[15] - PM7/PM8[70] - LLC - PM2[600] - LLD[70] - LLA/LLB[20]
        :return:
        """
        job_f = Job(name="Job_F",
                    ops_nums=7,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [2], 6: [14], 7: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [0], 5: [600], 6: [70], 7: [20]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [1], 6: [1], 7: [2]}
                    )
        return job_f

    def generator_job_g(self) -> Job :
        """
        工艺路径为 G 的工件
         AL[8] - LLA/LLB[15] - PM7/PM8[70] - LLC - PM3[600] - LLD[70] -  LLA/LLB[20]
        :return:
        """
        job_g = Job(name="Job_G",
                    ops_nums=7,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [3], 6: [14], 7: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [0], 5: [600], 6: [70], 7: [20]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [1], 6: [1], 7: [2]})
        return job_g


    def generator_job_h(self) -> Job :
        """
        工艺路径为 H 的工件
        AL[8] - LLA/LLB[15]- PM7/PM8[70] - LLC - PM4[600] - LLD[70] -  LLA/LLB[20]
        :return:
        """
        job_h = Job(name="Job_H",
                    ops_nums=7,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [4], 6: [14], 7: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [0], 5: [600], 6: [70], 7: [20]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [1], 6: [1], 7: [2]})
        return job_h

    def generator_job_i(self) -> Job :
        """
            I工件
            AL[8] - LLA/LLB[15] -PM7/PM8[70]-PM9[200]-LLD[70]-LLA/LLB[20]
        """
        job_i = Job(name="Job_I",
                    ops_nums=6,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [9], 5: [14], 6: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [200], 5: [70], 6: [20]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [2], 6: [2]})
        return job_i

    def generator_job_j(self) -> Job :
        """
        工艺路径为 J 的工件
        AL[8] - LLA/LLB[15]-PM7/PM8[70]-PM10[200]-LLD[70]-LLA/LLB[20]
        :return:
        """
        job_j = Job(name="Job_J",
                    ops_nums=6,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [10], 5: [14], 6: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [200], 5: [70], 6: [20]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [1], 6: [2]})
        return job_j

    def generator_job_k(self) -> Job :
        """
        工件K
        AL[8] - LLA/LLB[15] -PM7/PM8[70]-LLC-PM1/PM2/PM3/PM4[600]-LLD-PM9/PM10[200]-LLA/LLB[90]
        :return:
        """
        job_k = Job(name="Job_K",
                    ops_nums=8,
                    feasible_rules={1: [15], 2: [11, 12], 3: [7, 8], 4: [13], 5: [1, 2, 3, 4], 6: [14], 7: [9, 10], 8: [11, 12]},
                    process_time_rules={1: [8], 2: [15], 3: [70], 4: [0], 5: [600], 6: [0], 7: [200], 8: [90]},
                    transport_rules={1: [1], 2: [1], 3: [2], 4: [2], 5: [1], 6: [1], 7: [2], 8: [2]}
                    )
        return job_k


class Task:
    """任务类：封装一个任务包含的所有工件类型及对应数量"""

    def __init__(self, name: str, job_types: List[Job], job_counts: List[int], K: List[int] = K, R: List[int] = R ):
        self.name = name  # 任务名称
        self.job_types = job_types   # 任务包含的工件类型列表
        self.job_counts = job_counts  # 每种工件的数量（与工件类型列表顺序对应）
        self.K = K # 机器编号
        self.R = R # 机械手编号


    def __post_init__(self):
        """初始化后自动验证参数合法性"""
        if len(self.job_types) != len(self.job_counts):
            raise ValueError("工件类型列表与数量列表长度必须一致")
        if any(count <= 0 for count in self.job_counts):
            raise ValueError("工件数量必须为正整数")
        if not self.K or not isinstance(self.K, list) or any(k <= 0 for k in self.K):
            raise ValueError("机器列表K必须为非空正整数列表")
        if not self.R or not isinstance(self.R, list) or any(r <= 0 for r in self.R):
            raise ValueError("机械手列表R必须为非空正整数列表")

    def print_task_info(self):
        """打印任务的详细信息，包括名称、工件类型、数量及设备配置"""
        print(f"===== 任务信息：{self.name} =====")

        # 打印工件类型及数量
        print("\n包含工件类型及数量：")
        for idx, (job, count) in enumerate(zip(self.job_types, self.job_counts), 1):
            print(f"  {idx}. 工件名称：{job.name}，工序数：{job.ops_nums}，数量：{count}个")

        # 打印机器配置
        print(f"\n可用机器编号：{self.K}")

        # 打印机械手配置
        print(f"可用机械手编号：{self.R}")

        print("\n" + "=" * 30)  # 结束分隔线


# 使用示例（假设已定义Job类及实例）
if __name__ == "__main__":
    # 创建工件
    job_creator = create_job()
    job_b = job_creator.generator_job_b()
    job_c = job_creator.generator_job_c()

    # 创建任务实例
    task = Task(
        name="任务-5c",
        job_types=[job_b, job_c],
        job_counts=[25,50]
    )

    # 打印任务信息
    task.print_task_info()



